from bitstring import BitStream, BitArray
from utils import BYTE, BCD, WORD, formatter
from utils import FLAG_CODE_808 as FLAG_CODE
import ParserWrapper as BodyParserWrapper


def parse_msg(bitstream: BitStream):
    parse_result = {}

    # 标识位校验
    flag1 = bitstream.read("uint:8")
    bitstream.pos = bitstream.length - BYTE
    flag2 = bitstream.read("uint:8")
    if flag1 == flag2 == FLAG_CODE:
        pass
    else:
        raise ValueError("Invalid flag code")

    # 循环冗余码校验
    bitstream.pos = bitstream.length - BYTE * 2
    check_code = bitstream.read("hex:8")
    bitstream.pos = BYTE
    byte1 = byte2 = None
    while bitstream.pos < bitstream.length - BYTE * 2:
        if byte1 is None:
            byte1 = BitArray(hex=bitstream.read('hex:8'))
        else:
            byte2 = BitArray(hex=bitstream.read('hex:8'))
        if byte1 is not None and byte2 is not None:
            byte1 = byte1 ^ byte2
    bitstream.pos = BYTE
    if byte1.hex != check_code:
        raise ValueError("CRC Test Failed! Should be {}".format(byte1.hex))

    # 消息头解析
    head_fmt = formatter(f"""
        hex:{WORD}=message_id,
        hex:{WORD}=body_attribute,
        hex:{6*BCD}=phone_number,
        hex:{WORD}=message_number,
        """)
    head = bitstream.readlist(head_fmt)
    parse_result.setdefault("message_id", head[0])
    parse_result.setdefault("body_attribute", head[1])
    parse_result.setdefault("phone_number", head[2])
    parse_result.setdefault("message_number", int(head[3], base=16))

    # 消息体属性解析
    attribute_fmt = formatter("""
    bin:2=remain,
    bin:1=separate,
    bin:3=encrypt_method,
    bin:10=body_length,
    """)
    attribute_stream = BitStream(hex=parse_result['body_attribute'])
    attribute = attribute_stream.readlist(attribute_fmt)
    parse_result.setdefault("separate", True if attribute[1] == '1' else False)
    parse_result.setdefault("encrypt_method", 'RSA' if attribute[2] == '001' else None)
    parse_result.setdefault("body_length", int(attribute[3], 2))

    # 如果消息体属性中指定了分包，则进行消息包封装顶解析
    if parse_result['separate']:
        msg_sep_fmt = formatter(f"""
        uint:{WORD}=pkt_total,
        uint:{WORD}=pkt_no,
        """)
        pkt_sep_info = bitstream.readlist(msg_sep_fmt, word=WORD)
        parse_result.setdefault("pkt_total", pkt_sep_info[0])
        parse_result.setdefault("pkt_no", pkt_sep_info[1])

    # 消息体解析
    body = bitstream.readlist(f"hex:{parse_result['body_length']*8}")[0]
    parse_result.setdefault("body", body)

    return parse_result


if __name__ == '__main__':
    msg =  '7e0001000501571970845400010000000001eb7e'
    msg2 = '7e01000021015719708454000100010001000000000100000000000000010000000000000101b8ca4e4448393731c17e'
    msg_stream = BitStream(hex=msg2)
    msg = parse_msg(msg_stream)
    print(msg)
    body = BitStream(hex=msg['body'])
    body_res = BodyParserWrapper.parse(body, msg['message_id'])
    print(body_res)
